#pragma once
#include "../CGIResource.h"
#include "VulkanSemaphore.h"
#include "VulkanDevice.h"
#include "VulkanResource.h"
#include "VulkanSwapChain.h"
#include "Runtime/Utils/SmartPtr.h"

namespace Alice{
    class VulkanViewport;
    class CGICommandListImmediate;
    class CGIVulkanBackBuffer : public CGIVulkanTexture
    {
    public:
        VulkanViewport* mViewport;
        CGIVulkanBackBuffer(VulkanDevice& Device, VulkanViewport* InViewport, EPixelFormat Format, uint32 SizeX, uint32 SizeY, ETextureCreateFlags UEFlags);
        uint32 OnGetBackBufferImage(CGICommandListImmediate& inCGICmdList);
        uint32 AcquireBackBufferImage(VulkanCommandListContext& Context);
    };
    class VulkanViewport : public CGIViewport {
    public:
        VulkanDevice* mDevice;
        VkImage mImage;
        uint32 SizeX;
        uint32 SizeY;
        bool bIsFullscreen;
        EPixelFormat PixelFormat;
        int32 mAcquiredImageIndex;
        VulkanSwapChain* mSwapChain;
        void* WindowHandle;
        uint32 PresentCount;
        bool bRenderOffscreen;

        int8 LockToVsync;
        std::vector<CGIVulkanTexture*> mBackBufferImages;
        std::vector<CGIVulkanView*> mTextureViews;
        std::vector<VulkanSemaphore*> mRenderingDoneSemaphores;
        CGIVulkanBackBuffer* mCGIBackBuffer;
        VulkanSemaphore* mAcquiredSemaphore;
        VulkanViewport(VulkanDevice* InDevice, void* InWindowHandle, uint32 InSizeX,uint32 InSizeY,bool bInIsFullscreen, EPixelFormat InPreferredPixelFormat);
        void CreateSwapChain(VulkanSwapChainRecreateInfo*inVulkanSwapChainRecreateInfo);
        SmartPtr<CGITexture> GetBackBuffer(CGICommandListImmediate& CGICmdList,uint32&inOutImageIndex);
        bool TryAcquireImageIndex();
        void* GetNativeBackBufferRT() const
        {
            return mCGIBackBuffer;
        }
        bool Present(VulkanCommandListContext* Context, VulkanCommandBuffer* CmdBuffer, VulkanQueue* Queue, VulkanQueue* PresentQueue, bool bLockToVsync);
    };
}
